home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 February: Tool Chest / Apple Developer CD Series Tool Chest February 1996 (Apple Computer)(1996).iso / Sample Code / LabelMenu / LabelMenu.c < prev    next >
Encoding:
Text File  |  1995-06-16  |  13.3 KB  |  419 lines  |  [TEXT/MMCC]

  1. //
  2. //    Application:    LabelMenu
  3. //    
  4. //    Description:    This demonstrates a program with a Finder-like label menu.
  5. //                    Each label menu item has a 12x16 pixel 'cicn and the
  6. //                    color and name of all the items are updated if the user
  7. //                    changes anything in the "Labels" control panel.
  8. //                    This also demonstrates how to change a menu tile to an icon.
  9. //    
  10. //    Programmer:        David Hayward
  11. //                    Developer Technical Support
  12. //                    Apple Computer, Inc.
  13. //
  14. //    Environment:    Metrowerks C version 6, Universal Interfaces 2.0
  15. //
  16. //    History:        11/23/93
  17. //                      first draft
  18. //                    4/8/94 
  19. //                      updated project to use the new Universal Header
  20. //                      added routine to change a menu title
  21. //                      added abillity to change Label menu's title to a small icon
  22. //                      (for info on how this is done see IM:Text page 7-39
  23. //                    5/12/95
  24. //                      updated project for Metrowerks
  25. //    
  26.  
  27.  
  28. #include <desk.h>
  29. #include <dialogs.h>
  30. #include <fonts.h>
  31. #include <icons.h>
  32. #include <windows.h>
  33. #include <memory.h>
  34. #include <menus.h>
  35. #include <quickdraw.h>
  36. #include <resources.h>
  37. #include <toolutils.h>
  38. #include <types.h>
  39.  
  40. #include "InitMac.h"
  41.  
  42.  
  43. /**\
  44. |**| ==============================================================================
  45. |**| ENUMS
  46. |**| ==============================================================================
  47. \**/
  48. enum { kWindID=128 } ;
  49. enum { kMBarID=128 } ;
  50. enum { kAppleMenu=128, kFileMenu, kEditMenu, kLabelMenu, kSpecialMenu } ;
  51. enum { kNewItem=1, kOpenItem, kCloseItem, kSaveItem,
  52.         kSaveAsItem, kFileBlank1, kPageSetupItem,
  53.         kPrintItem, kFileBlank2, kQuitItem } ;
  54. enum { kDimLabel=1, kUseIcon } ;
  55. enum { kLabelIconID=1024 } ;
  56.  
  57.  
  58. /**\
  59. |**| ==============================================================================
  60. |**| GLOBALS
  61. |**| ==============================================================================
  62. \**/
  63. WindowPtr    gWindow;
  64. Boolean        gDone = false;
  65. Str255        gString = "\pInitial string";            /* default display string */
  66. Str255        LabelIconStr = "\p\01XXXX";                /* a five character string used to change label */
  67.                                                     /* menu's title to a small icon:
  68.                                                     /*   Byte 0 = 0x05 = length if p-string */
  69.                                                     /*   Byte 1 = 0x01 = invalid character code */
  70.                                                     /*   Byte 2-5 = handle to icon suite */
  71. short        theLabelItem=1;                            /* default label menu item (none) */
  72. Handle        theLabelIcon;
  73.  
  74.  
  75. /**\
  76. |**| ==============================================================================
  77. |**| FUNCTION PROTOTYPES
  78. |**| ==============================================================================
  79. \**/
  80. void    main            ( void ) ;
  81. void    SetUpMenus        ( void ) ;
  82. void    CreateWindow    ( void ) ;
  83. void    SetupLabelMenu    ( void ) ;
  84. short    Label2Item        ( short label ) ;
  85. short    Item2Label        ( short item ) ;
  86. void    DoCommand        ( long mResult ) ;
  87. void    DoUpdate        ( WindowPtr whichWindow ) ;
  88. void    DoMouseDown        ( EventRecord event ) ;
  89. void    DoOSEvent        ( EventRecord event ) ;
  90. void    DoEventLoop        ( void );
  91.  
  92. extern void    SetMenuTitle    (MenuHandle theMenu, Str255 theNewTitle);
  93.  
  94.  
  95. /**\
  96. |**| ==============================================================================
  97. |**| PRIVATE FUNCTIONS
  98. |**| ==============================================================================
  99. \**/
  100.  
  101.  
  102. /*------------------------------------------------------------------------------*\
  103.     main
  104.  *------------------------------------------------------------------------------*
  105.         a fairly normal main function.
  106. \*------------------------------------------------------------------------------*/
  107. void main ( void )
  108. {
  109.     InitToolBox( 4 ) ;
  110.     SetUpMenus() ;
  111.     CreateWindow() ;            /* create main window */
  112.     DoEventLoop() ;
  113. }
  114.  
  115.  
  116. /*------------------------------------------------------------------------------*\
  117.     SetUpMenus
  118.  *------------------------------------------------------------------------------*
  119.         load in and draw the menu bar.
  120. \*------------------------------------------------------------------------------*/
  121. void SetUpMenus ( void )
  122. {
  123.     Handle        hMenuBar ;
  124.     long        *longPtr ;
  125.  
  126.     hMenuBar = GetNewMBar( kMBarID ) ;
  127.     SetMenuBar( hMenuBar ) ;
  128.     AddResMenu( GetMHandle(kAppleMenu), 'DRVR' ) ;
  129.     SetupLabelMenu() ;
  130.     DrawMenuBar() ;
  131.     
  132.     /* get icon suite for lable menu */
  133.     GetIconSuite( &theLabelIcon, kLabelIconID, svAllSmallData ) ;
  134.     HNoPurge( (Handle)theLabelIcon ) ;
  135.     
  136.     /* stuff the handle for the suite into chars 2-5 of the label string */
  137.     longPtr = (long *)&(LabelIconStr[2]) ;
  138.     *longPtr = (long)theLabelIcon ;
  139. }
  140.  
  141.  
  142. /*------------------------------------------------------------------------------*\
  143.     CreateWindow
  144.  *------------------------------------------------------------------------------*
  145.         Create a normal window in front and a big
  146.         window in back to obscure the Finder.
  147. \*------------------------------------------------------------------------------*/
  148. void CreateWindow ( void )
  149. {
  150.     gWindow = GetNewCWindow( kWindID, nil, nil ) ;
  151. }
  152.  
  153.  
  154. /*------------------------------------------------------------------------------*\
  155.     SetupLabelMenu
  156.  *------------------------------------------------------------------------------*
  157.         this function updates the label menu so that the items contain the
  158.         current label text and color.  note that this uses the trick of
  159.         directly changing the color in the the icon of each item.  The offset
  160.         of 29 for the RGB color will only work for the included 24x12 'cicn's
  161. \*------------------------------------------------------------------------------*/
  162. void SetupLabelMenu ( void )
  163. {
  164.     Str255        labelString ;
  165.     RGBColor    labelColor ;
  166.     short        label, item, rID, depth ;
  167.     CIconHandle    cicon ;
  168.     GDHandle    gdh ;
  169.     MenuHandle    LabelMenuHdl ;
  170.     
  171.     LabelMenuHdl = GetMHandle( kLabelMenu ) ;
  172.     gdh = GetMainDevice() ;                                /* get device with the menu bar */
  173.     depth = (**(**gdh).gdPMap).pixelSize;                /* get the depth of this screen */
  174.  
  175.                                                         /* special case for 1st label */
  176.                                                         /* because "none" item has no */
  177.     GetLabel( 0, &labelColor, labelString ) ;            /* icon next to it */
  178.     SetItem( LabelMenuHdl, 1, labelString ) ;            /* set label string */
  179.     
  180.     for ( label=1; label<8; label++ )                    /* loop through other labels... */
  181.     {
  182.         item = Label2Item( label ) ;                    /* calc menu item for this label */
  183.  
  184.         GetLabel( label, &labelColor, labelString ) ;    /* get the label string and color */
  185.         SetItem( LabelMenuHdl, item, labelString ) ;    /* set label string */
  186.  
  187.         if ( depth<=2 )                                    /* if screen too shallow... */
  188.             SetItemIcon( LabelMenuHdl, item, 0 ) ;        /* turn off the menu item's 'cicn' */
  189.         else                                            /* if screen deep enough... */
  190.         {
  191.             rID = 310 + label - 256 ;                    /* calclate 'cicn' code */
  192.             SetItemIcon( LabelMenuHdl, item, rID ) ;    /* set it for the menu item */
  193.             
  194.             cicon = (CIconHandle)GetResource('cicn', rID+256) ;
  195.             
  196.             if ( cicon!=nil )                            /* resource was found */
  197.             {
  198.                 short *iMaskData = (**cicon).iconMaskData ;
  199.                 iMaskData[29] = labelColor.red ;        /* change the color */
  200.                 iMaskData[30] = labelColor.green ;
  201.                 iMaskData[31] = labelColor.blue ;
  202.             }
  203.         }
  204.     }
  205. }
  206.  
  207.  
  208. /*------------------------------------------------------------------------------*\
  209.     Label / Item conversions
  210.  *------------------------------------------------------------------------------*
  211.         the standard order for labels in a menu is backwards so here
  212.         are functions to convert back and forth. these could be #defines.
  213. \*------------------------------------------------------------------------------*/
  214. short Label2Item ( short label )
  215. {    return ( (label==0) ? (0) : (10-label) ) ;
  216. }
  217. short Item2Label ( short item )
  218. {    return ( (item==0) ? (0) : (10-item) ) ;
  219. }
  220.  
  221.  
  222. /*------------------------------------------------------------------------------*\
  223.     DoCommand
  224.  *------------------------------------------------------------------------------*
  225.         handle menu events.
  226. \*------------------------------------------------------------------------------*/
  227. void DoCommand ( long mResult )
  228. {
  229.     short        item, menu, mark ;
  230.     MenuHandle    mHandle ;
  231.     
  232.     item = LoWord( mResult ) ;
  233.     menu = HiWord( mResult ) ;
  234.     mHandle = GetMHandle( menu ) ;
  235.  
  236.     if ( (menu!=0) && (item!=0) )                        /* if any menu item ... */
  237.     {
  238.         GetItem( mHandle, item, gString ) ;                /* get the item's text */
  239.         SetPort( (GrafPtr)gWindow ) ;
  240.         InvalRect( &(gWindow->portRect) ) ;                /* start and update event */
  241.     }
  242.     
  243.     switch (menu)
  244.     {
  245.         case kLabelMenu :                                /* if the the label menu... */
  246.             CheckItem( mHandle, theLabelItem, false ) ;    /* uncheck the old */
  247.             CheckItem( mHandle, item, true ) ;            /* check the new */
  248.             theLabelItem = item ;                        /* remember the item */
  249.             break ;
  250.     
  251.         case kSpecialMenu :                                /* if the the Special menu... */
  252.             if ( item==kDimLabel )                        /* if dim label item... */
  253.             {
  254.                 GetItemMark( mHandle, item, &mark ) ;    /* determine if already checked */
  255.                 CheckItem( mHandle, item, !mark ) ;        /* check/uncheck the item */
  256.                 if (mark==0)                            /* dim/undim the label menu */
  257.                     DisableItem( GetMHandle(kLabelMenu), 0 ) ;
  258.                 else
  259.                     EnableItem( GetMHandle(kLabelMenu), 0 ) ;
  260.                 DrawMenuBar() ;                            /* update the menu bar */
  261.             }
  262.             if ( item==kUseIcon )
  263.             {
  264.                 GetItemMark( mHandle, item, &mark ) ;    /* determine if already checked */
  265.                 CheckItem( mHandle, item, !mark ) ;        /* check/uncheck the item */
  266.                 if ( mark==0 )                            /* change the label menu to show icon*/
  267.                     SetMenuTitle( GetMHandle(kLabelMenu), LabelIconStr ) ;
  268.                 else
  269.                     SetMenuTitle( GetMHandle(kLabelMenu), "\pLabel" ) ;
  270.             }
  271.             break ;
  272.     
  273.         case kFileMenu :                                /* if the the file menu... */
  274.             if ( item==kQuitItem )                         /* if quit item... */
  275.                 gDone = true ;
  276.             break ;
  277.     }
  278.     HiliteMenu(0);                                        /* un-hilight the chosen menu item */
  279. }
  280.  
  281.  
  282. /*------------------------------------------------------------------------------*\
  283.     DoUpdate
  284.  *------------------------------------------------------------------------------*
  285.         handle update events.
  286. \*------------------------------------------------------------------------------*/
  287. void DoUpdate ( WindowPtr window )
  288. {
  289.     RGBColor    labelColor = {0,0,0} ;
  290.     Str255        labelString ;
  291.  
  292.     BeginUpdate( window ) ;
  293.     SetPort( window ) ;                                    /* make sure we're in our port */
  294.  
  295.     GetLabel( Item2Label(theLabelItem),                    /* get the currently checked */
  296.               &labelColor, labelString) ;                /* label's rgb color */
  297.     RGBForeColor( &labelColor ) ;                        /* set it as the fore color */
  298.  
  299.     EraseRect( &((GrafPtr)window)->portRect ) ;            /* erase the old stuff */
  300.     
  301.     TextSize( 24 ) ;
  302.     MoveTo( 20, 80 ) ;
  303.     DrawString( gString ) ;                                /* draw the string */
  304.     
  305.     EndUpdate( window ) ;
  306. }
  307.  
  308.  
  309. /*------------------------------------------------------------------------------*\
  310.     DoMouseDown
  311.  *------------------------------------------------------------------------------*
  312.         handle DoMouseDown events.
  313. \*------------------------------------------------------------------------------*/
  314. void DoMouseDown ( EventRecord event )
  315. {
  316.     WindowPtr   window ;
  317.     short       clickArea ;
  318.     Rect        screenRect ;
  319.  
  320.     clickArea = FindWindow( event.where, &window ) ;
  321.     screenRect = (**GetGrayRgn()).rgnBBox ;
  322.     
  323.     switch ( clickArea )
  324.     {
  325.         case inSysWindow: 
  326.             SystemClick( &event, window ) ;
  327.             break;
  328.  
  329.         case inMenuBar:                        /* handle menu selections */
  330.             DoCommand( MenuSelect(event.where) ) ;
  331.             break;
  332.  
  333.         case inDrag :                        /* handle window drags */
  334.             DragWindow( window, event.where, &screenRect ) ;
  335.             break;
  336.             
  337.         case inContent :                    /* Handle content clicks */
  338.     //        if ( window != FrontWindow() )    /* if click is in a back window */
  339.     //            if ( window != gBackWind )    /* and its not gBackWind */
  340.     //                SelectWindow( window ); /* the bring it to front */
  341.             break;
  342.             
  343.         case inGoAway :
  344.     //        if ( TrackGoAway(window,event.where) )
  345.     //            HideWindow( window ) ;        /* hide the window */
  346.     //        if ( window==gForeWind )        /* if it was the fore wind */
  347.     //            gForeVis = false ;            /* then update its state global */
  348.             break;
  349.     }
  350. }
  351.  
  352.  
  353. /*------------------------------------------------------------------------------*\
  354.     DoOSEvent
  355.  *------------------------------------------------------------------------------*
  356.         handle DoOSEvent events.
  357. \*------------------------------------------------------------------------------*/
  358. void DoOSEvent ( EventRecord event )
  359. {
  360.     long        mssg ;
  361.  
  362.     mssg = event.message ;
  363.     if ( (mssg>>24)==suspendResumeMessage )    /* if high byte of message indicates */
  364.     {                                          /* this is suspend/resume event */
  365.         if ( mssg & resumeFlag )                        /* if resume event */
  366.         {
  367.             /* we're switching back from another app so we need to update */
  368.             /* the label menu in case the user changed the labels */
  369.             SetupLabelMenu() ;
  370.         }
  371.         else                                            /* if suspend event */
  372.         {
  373.             /* we're switching to another app */
  374.         }
  375.     }
  376. }
  377.  
  378.  
  379. /*------------------------------------------------------------------------------*\
  380.     DoEventLoop
  381.  *------------------------------------------------------------------------------*
  382.         Keep doing an event loop until the user quits.
  383. \*------------------------------------------------------------------------------*/
  384. void DoEventLoop ( void )
  385. {
  386.     EventRecord event ;
  387.     WindowPtr   window ;
  388.     long        mssg ;
  389.  
  390.     while ( !gDone ) 
  391.     {
  392.         if ( WaitNextEvent(everyEvent,&event,30,nil) )
  393.         {
  394.             mssg = event.message ;
  395.             switch ( event.what )
  396.             {
  397.                 case mouseDown :                        /* handle mouse clicks */
  398.                     DoMouseDown( event ) ;
  399.                     break ;
  400.                 
  401.                 case keyDown :                            /* handle key hits */
  402.                 case autoKey :
  403.                     if ( event.modifiers & cmdKey )        /* handle command keys */
  404.                         DoCommand(MenuKey( mssg & charCodeMask) ) ;
  405.                     break ;
  406.                     
  407.                 case updateEvt :                        /* handle update events */
  408.                     DoUpdate( (WindowPtr)mssg ) ;
  409.                     break ;
  410.                 
  411.                 case osEvt:                                /* handle os events */
  412.                     DoOSEvent( event ) ;
  413.                     break ;
  414.             }
  415.         }
  416.     }
  417. }
  418.  
  419.